package org.nobject.common.text;

import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;


/**
 * 准确挖取出正对标签体，以及带属性判断标签
 * */
public class TagUtils {
	
	/** 
	 * 找配对标签体
	 * 
	 * @param source 源
	 * @param beginIndex 初始点
	 * @param start 前部
	 * @param end 尾部
	 *  */
	public static String findCouple(String source,String startTagSign,String tag){
		List l=findCouples(source, startTagSign, tag);
		return l!=null&&l.size()>0?(String)l.get(0):null;
	}
	
	/** findCouples */
	public static List findCouples(String source,String startTagSign,String tag){
		List list=new LinkedList();
		int beginIndex=source.indexOf(startTagSign);
		if(beginIndex<=0) return list;
		int lc=beginIndex+startTagSign.length();
		int lev=1;
		String startTag="<"+tag;
		String endTag="</"+tag+">";
		int pBeginIndex=beginIndex;
		while(lc>=0){
			int cs=source.indexOf(startTag,lc);
			int ce=source.indexOf(endTag,lc);
			if(cs>=0&&(cs<ce||ce<0)){
				lev++;
				lc=cs+startTag.length();
				//System.out.println(lev+"-find:"+startTag+" at "+lc+"-more:"+source.substring(lc));
			}else if(ce>=0&&(cs>ce||cs<0)){
				if(lev>=0) lev--;
				lc=ce+endTag.length();
				//System.out.println(lev+"-find:"+endTag+" at "+lc+"-more:"+source.substring(lc));
				if(lev==0) {
					String part=source.substring(pBeginIndex,lc);
					list.add(part);
					//System.out.println("pBeginIndex:"+pBeginIndex+",lc:"+lc);
					//System.out.println("保存:"+part);
					lc=source.indexOf(startTagSign,lc);
					if(lc<0) break;
					lc+=startTagSign.length();
					lev=1;
					pBeginIndex=cs;
				}
			}else{
				break;
			}
			//System.out.println("change lev:"+lev);
		}
		return list;
	}
	
	/**
	 * 状态 枚举
	 *
	 * @author bianrongjun
	 * @version 1.0
	 */
	public static enum STATUS {
		/**
		 *结束 
		 */
		END, 
		
		/**
		 * 标签开始
		 * */
		TARG_BEGIN,
		
		/**
		 * 标签名开始
		 */
		TARGNAME_BEGIN, //22
		/**
		 * 标签名结束
		 */
		TARGNAME_END, 
		/**
		 * 标签名后空格
		 */
		TARGNAME_SPACE,
		/**
		 * 属性名开始
		 */
		ATTRNAME_BEGIN,
		/**
		 * 属性名空格
		 */
		ATTRNAME_SPACE,
		/**
		 * 属性名等号
		 */
		ATTRNAME_EQUAL,
		/**
		 * 属性内容开始
		 */
		ATTRVALUE_BEGIN,
		/**
		 * 头部开始结束
		 * */
		HEAD_BEGIN_CLOSE,
		/**
		 * 头部标签结束
		 */
		HEAD_TARG_END,
		/**
		 * 尾部标签开始
		 */
		FOOT_TARGNAME_BEGIN,
		
		/**
		 * 尾部标签结束
		 */
		FOOT_TARGNAME_END,
		/**
		 * 标签结束
		 */
		TAG_END
	}
	
	/**
	 * 起始位置
	 */
	public static String ANALYZE_STARTPOINT="ANALYS_STARTPOINT";
	
	/**
	 * 结束位置
	 */
	public static String ANALYZE_ENDPOINT="ANALYS_ENDPOINT";
	
	/**
	 * 源字符串
	 */
	public static String ANALYZE_SOURCECHARS="ANALYZE_SOURCECHARS";
	
	/**
	 * 属性
	 */
	public static String ANALYZE_ATTRIBUTES="ANALYZE_ATTRIBUTES";
	
	/**
	 * analys
	 * @param content
	 * @param targName
	 * @param params
	 * @param egnoreCase
	 * @return
	 */
	public static Map analyze(String content, String targName,Map params,boolean egnoreCase) {
		
		//初始化
		int sourceLength = content.length();
		char[] sourceChars = new char[sourceLength];
		content.getChars(0, sourceLength, sourceChars, 0);

		int targLength = targName.length();
		char[] tarChars = new char[targLength];
		targName.getChars(0, targLength, tarChars, 0);

		
		int targNamePoint=0;
		String tmpstr;
		STATUS findstatus = STATUS.END;
		
		
		int startPoint=-1;//起始位置
		int endPoint=-1;//结束位置
		
		Map m=null;
		Map attributes=new HashMap();
		
		boolean end=false;
		
		//Map targMap=new HashMap();
		
		//开始寻找
		for (int i = 0; i < sourceLength&&!end; i++) {
			switch(findstatus){
			case END:
				if(sourceChars[i]=='<'){
					findstatus=STATUS.TARG_BEGIN;
					targNamePoint=0;
					startPoint=i;
				}
				break;
			case TARG_BEGIN:
				System.err.println("TARG_BEGIN");
				if(sourceChars[i]==tarChars[targNamePoint]){
					if(targNamePoint+1==targLength){
						findstatus=STATUS.END;
					}else{
						findstatus=STATUS.TARGNAME_BEGIN;
						targNamePoint++;
					}
				}else if(sourceChars[i]=='/'){
					findstatus=STATUS.FOOT_TARGNAME_BEGIN;
				}else{
					targNamePoint=0;findstatus=STATUS.END;//失败
				}
				break;
			case TARGNAME_BEGIN:
				System.err.println("TARGNAME_BEGIN");
				if(sourceChars[i]==tarChars[targNamePoint]){
					if(targNamePoint+1==targLength){
						findstatus=STATUS.END;
					}else{
						targNamePoint++;
					}
				}else{
					targNamePoint=0;findstatus=STATUS.END;//失败
				}
				break;
			case TARGNAME_END:
				System.err.println("TARGNAME_END");
				tmpstr=new String(new char[]{sourceChars[i]});
				if(tmpstr.matches("\\s")){
					findstatus=STATUS.TARGNAME_SPACE;
				}else if(sourceChars[i]=='>'){
					findstatus=STATUS.HEAD_TARG_END;
				}else if(sourceChars[i]=='/'){
					findstatus=STATUS.HEAD_BEGIN_CLOSE;
				}else{
					findstatus=STATUS.END;
				}
				break;
			case TARGNAME_SPACE:
				tmpstr=new String(new char[]{sourceChars[i]});
				if(tmpstr.matches("\\s")){
					//
				}else if(tmpstr.matches("[a-zA-Z]")){
					findstatus=STATUS.ATTRNAME_BEGIN;
				}else if(sourceChars[i]=='>'){
					findstatus=STATUS.HEAD_TARG_END;
				}else if(sourceChars[i]=='/'){
					findstatus=STATUS.HEAD_BEGIN_CLOSE;
				}else{
					findstatus=STATUS.END;
				}
				break;
			case ATTRNAME_BEGIN:
				tmpstr=new String(new char[]{sourceChars[i]});
				if(tmpstr.matches("[0-9a-zA-Z$_]")){
					//
				}else if(sourceChars[i]=='='){
					findstatus=STATUS.ATTRNAME_EQUAL;
				}else if(tmpstr.matches("\\s")){
					findstatus=STATUS.ATTRNAME_SPACE;
				}else{
					findstatus=STATUS.END;
				}
				break;
			case ATTRNAME_SPACE:
				tmpstr=new String(new char[]{sourceChars[i]});
				if(tmpstr.matches("\\s")){
					//
				}else if(sourceChars[i]=='='){
					findstatus=STATUS.ATTRNAME_EQUAL;
				}else{
					findstatus=STATUS.END;
				}
				break;
			case ATTRNAME_EQUAL:
				tmpstr=new String(new char[]{sourceChars[i]});
				if(sourceChars[i]=='"'){
					findstatus=STATUS.ATTRVALUE_BEGIN;
				}else if(tmpstr.matches("\\s")){
					//
				}else{
					findstatus=STATUS.END;
				}
				break;
			case ATTRVALUE_BEGIN:
				if(sourceChars[i]=='"'){
					findstatus=STATUS.TARGNAME_END;
				}else{
					//记录VALUE值
				}
				break;
			case HEAD_BEGIN_CLOSE:
				tmpstr=new String(new char[]{sourceChars[i]});
				if(tmpstr.matches("\\s")){
					//
				}else if(sourceChars[i]=='>'){
					endPoint=i;
					end=true;
					findstatus=STATUS.TAG_END;
				}else{
					findstatus=STATUS.END;
				}
			case HEAD_TARG_END:
				if(sourceChars[i]=='<'){
					findstatus=STATUS.TARG_BEGIN;
				}else{
					//
				}
				break;
			case FOOT_TARGNAME_BEGIN:
				if(sourceChars[i]==tarChars[targNamePoint]){
					if(targNamePoint+1==targLength){
						findstatus=STATUS.FOOT_TARGNAME_END;
					}else{
						targNamePoint++;
					}
				}else{
					targNamePoint=0;findstatus=STATUS.END;//失败
				}
				break;
			case FOOT_TARGNAME_END:
				tmpstr=new String(new char[]{sourceChars[i]});
				if(tmpstr.matches("\\s")){
					findstatus=STATUS.FOOT_TARGNAME_END;
				}else if(sourceChars[i]=='>'){
					endPoint=i;
					end=true;
					findstatus=STATUS.TAG_END;
				}else{
					findstatus=STATUS.END;
				}
				break;
			case TAG_END:
				end=true;
				findstatus=STATUS.END;
				break;
			}
			
			if(endPoint>0){
				m=new HashMap();
				m.put(ANALYZE_STARTPOINT, startPoint);
				m.put(ANALYZE_ENDPOINT, endPoint);
				m.put(ANALYZE_SOURCECHARS, sourceChars);
				m.put(ANALYZE_ATTRIBUTES, attributes);
			}
		}

		return m;
	}
	
	public String replace(String source,String targName,Map attributes,String replacement){
		//初始化
		int sourceLength = source.length();
		char[] sourceChars = new char[sourceLength];
		source.getChars(0, sourceLength, sourceChars, 0);
		
		int targStart=0;
		int targEnd=10;
		
		StringBuffer sb=new StringBuffer();
		sb.append(sourceChars,0,targStart).append(replacement).append(sourceChars,targEnd,sourceChars.length);
		return sb.toString();
	}
	
	public static void main(String[] args) {
		//String content=FileUtils.readFile("c:\\c.txt");
		//System.err.println(findCouple(content, "<a", "a"));
	}
	
	
	
}


